home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _skiplist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  7.2 KB  |  348 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _skiplist.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. //------------------------------------------------------------------------------
  16. //
  17. //  skip lists 
  18. //
  19. //  doubly linked
  20. //
  21. //  S. Naeher (1992)
  22. //
  23. //------------------------------------------------------------------------------
  24.  
  25.  
  26. #include <LEDA/impl/skiplist.h>
  27.  
  28. #define NODE_SIZE(l) sizeof(skiplist_node)+l*sizeof(skiplist_node*)
  29.  
  30. #define NEW_NODE(p,l) p=(skiplist_item)allocate_bytes(NODE_SIZE(l));p->level=l;
  31.  
  32. #define NEW_NODE_0(p,l) p=(skiplist_item)malloc(NODE_SIZE(l));p->level=l;
  33.  
  34. #define FREE_NODE(p) deallocate_bytes(p,NODE_SIZE(p->level))
  35.  
  36. #define FREE_NODE_0(p) free(p)
  37.  
  38.  
  39. const int BitsInRandom      = 31;
  40. const int MaxNumberOfLevels = 32;
  41.  
  42. skiplist::skiplist(float p) 
  43. { prob = p;
  44.   randomBits = random(0,MAXINT-1);
  45.   randomsLeft = BitsInRandom;
  46.   level = 0;
  47.   count = 0;
  48.  
  49.   NEW_NODE_0(header,MaxNumberOfLevels);
  50.   NEW_NODE_0(STOP,-1);
  51.   STOP->backward = header;
  52.   STOP->pred = header;
  53.  
  54.   for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  55.   header->backward = 0;
  56.   header->pred = 0;
  57.  
  58.  } 
  59.  
  60. skiplist::skiplist(const skiplist& L) 
  61. { prob = L.prob;
  62.   randomBits = random(0,MAXINT-1);
  63.   randomsLeft = BitsInRandom;
  64.   level = 0;
  65.   count = 0;
  66.  
  67.   NEW_NODE_0(header,MaxNumberOfLevels);
  68.   NEW_NODE_0(STOP,-1);
  69.   STOP->backward = header;
  70.   STOP->pred = header;
  71.  
  72.   for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  73.   header->backward = 0;
  74.   header->pred = 0;
  75.  
  76.  
  77.   skiplist_item p = L.STOP->pred;
  78.   while (p!= L.header) 
  79.   { insert_at_item(header,p->key,p->inf);
  80.     L.copy_key(p->key);
  81.     L.copy_inf(p->inf);
  82.     p = p->pred;
  83.    }
  84.  } 
  85.  
  86.  
  87. skiplist& skiplist::operator=(const skiplist& L) 
  88. { clear();
  89.   skiplist_item p = L.STOP->pred;
  90.   while (p!= L.header) 
  91.   { insert_at_item(header,p->key,p->inf);
  92.     p = p->pred;
  93.    }
  94.   return *this;
  95.  } 
  96.  
  97. void skiplist::clear() 
  98. { register skiplist_item p,q;
  99.   p = header->forward[0];
  100.   while(p!=STOP)
  101.   { q = p->forward[0];
  102.     clear_key(p->key);
  103.     clear_inf(p->inf);
  104.     FREE_NODE(p);
  105.     p = q; 
  106.    }
  107.  level = 0;
  108.  for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  109.  STOP->pred = header;
  110.  count = 0;
  111. }
  112.  
  113.  
  114.  
  115. skiplist::~skiplist() 
  116. { clear();
  117.   FREE_NODE_0(header);
  118.   FREE_NODE_0(STOP);
  119.  }
  120.  
  121.  
  122. int skiplist::randomLevel()
  123. {  register int level = 0;
  124.    register int b  = 0;
  125.  
  126.    if (prob==0.25)  
  127.       // while (random() < MAXINT/4) level++;
  128.       while (b==0)
  129.       { b = randomBits&3;    // read next two random bits
  130.         randomBits >>= 2;
  131.         randomsLeft -= 2;
  132.         if (b==0) level++;   // increase level with prob 0.25
  133.         if (randomsLeft < 2) 
  134.         { randomBits = random(0,MAXINT-1);
  135.           randomsLeft = BitsInRandom;
  136.          }
  137.        }
  138.    else            // user defined prob.
  139.      while (rrandom() < prob) level++;
  140.     
  141.    return level;
  142.  }
  143.  
  144.  
  145. skiplist_item skiplist::search(GenPtr key, int& l) const
  146. { register skiplist_item p = header;
  147.   register skiplist_item q;
  148.   register k,c=1;
  149.  
  150.   if (int_type())
  151.   { STOP->key = key;
  152.     for(k = level; k>=0; k--)
  153.     { q = p->forward[k];
  154.       while (long(key) > long(q->key)) 
  155.       { p = q;
  156.         q = p->forward[k];
  157.        }
  158.       if(key==q->key && q != STOP) break;
  159.      }
  160.    }
  161.   else
  162.   { for(k = level; k>=0; k--)
  163.     { q = p->forward[k];
  164.       while (k==q->level && (c=cmp(key,q->key)) > 0)
  165.       { p = q;
  166.         q = p->forward[k];
  167.        }
  168.       if(c==0) break;
  169.      }
  170.    }
  171.   l = k;
  172.   return q;
  173.  }
  174.  
  175.  
  176. skiplist_item skiplist::locate(GenPtr key) const
  177. { int k;
  178.   skiplist_item q = search(key,k);
  179.   return (q==STOP) ? q->pred : q;
  180.  }
  181.  
  182.  
  183. skiplist_item skiplist::locate_succ(GenPtr key) const
  184. { int k;
  185.   skiplist_item q = search(key,k);
  186.   if (q==header) return min();
  187.   if (cmp(key,q->key)!=0) q = q->forward[0];
  188.   return (q==STOP) ? 0 : q;
  189.  }
  190.  
  191. skiplist_item skiplist::locate_pred(GenPtr key) const
  192. { int k;
  193.   skiplist_item q = search(key,k);
  194.   if (q==STOP) return max();
  195.   if (cmp(key,q->key)!=0) q = q->pred;
  196.   return (q==header) ? 0 : q;
  197.  }
  198.  
  199.  
  200.  
  201.  
  202. skiplist_item skiplist::lookup(GenPtr key) const
  203. { int k;
  204.   skiplist_item q = search(key,k);
  205.   return (k<0) ? 0 : q;
  206.  }
  207.  
  208.  
  209. void skiplist::insert_item_at_item(skiplist_item q, skiplist_item p)
  210.   // insert item q immediately after item p
  211.  
  212.   register skiplist_item x;
  213.   register int k;
  214.   q->pred = p;
  215.   p->forward[0]->pred = q;
  216.   for(k=0; k<=q->level; k++)
  217.   { while (k > p->level) p = p->backward;
  218.     x = p->forward[k];
  219.     q->forward[k] = x;
  220.     p->forward[k] = q;
  221.     if (x->level == k) x->backward = q;
  222.    }
  223.    q->backward = p;
  224.  }
  225.  
  226.  
  227. skiplist_item skiplist::insert_at_item(skiplist_item p, GenPtr key, GenPtr inf)
  228. { register skiplist_item q;
  229.   register int k;
  230.  
  231.   if (p != header)
  232.   { int c = cmp(key,p->key);
  233.  
  234.     if (c == 0)
  235.     { clear_inf(p->inf);
  236.       copy_inf(inf);
  237.       p->inf = inf;
  238.       return p;
  239.      }
  240.  
  241.     if (c<0) p = p->pred;
  242.  
  243. /*
  244.      if (p!=min() && cmp(key,p->pred->key) <= 0)
  245.      {  cout << "wrong position for "; print_key(key);
  246.         newline;
  247.         cout << " pos = "; print_key(p->key);
  248.         newline;
  249.         cout << " pred = "; print_key(p->pred->key);
  250.         newline;
  251.         error_handler(1,"skiplist::insert_at : wrong position "); 
  252.       }
  253. */
  254.    }
  255.  
  256.    k = randomLevel();
  257.    if (k>level) k = ++level;
  258.  
  259.    NEW_NODE(q,k);
  260.    copy_key(key);
  261.    copy_inf(inf);
  262.    q->key = key;
  263.    q->inf = inf;
  264.    count++;
  265.  
  266.    insert_item_at_item(q,p);
  267.  
  268.    return q;
  269.  }
  270.  
  271.  
  272. void skiplist::remove_item(skiplist_item q)
  273. { register int k;
  274.   register skiplist_item p = q->backward;
  275.   register skiplist_item x;
  276.  
  277.   for(k=q->level; k>=0; k--)
  278.   { while (p->forward[k] != q) p = p->forward[k];
  279.     x = q->forward[k];
  280.     p->forward[k] = x;
  281.     if (x->level==k) x->backward = p;
  282.    }
  283.   x->pred = p;
  284. }
  285.  
  286.  
  287. void skiplist::del_item(skiplist_item q)
  288. { remove_item(q);
  289.   clear_key(q->key);
  290.   clear_inf(q->inf);
  291.   FREE_NODE(q);
  292.   while(header->forward[level] == STOP && level > 0 ) level--;
  293.   count --;
  294. }
  295.  
  296. skiplist_item skiplist::insert(GenPtr key, GenPtr inf)
  297. { int k;
  298.   skiplist_item p = search(key,k);
  299.   if (p==STOP) p = p->pred;
  300.   return insert_at_item(p,key,inf);
  301.  }
  302.  
  303. void skiplist::del(GenPtr key)
  304. { int k;
  305.   skiplist_item q = search(key,k);
  306.   if (k>=0) del_item(q);
  307.  }
  308.  
  309.  
  310. void skiplist::reverse_items(skiplist_item p, skiplist_item q)
  311. { skiplist_item r;
  312.   while (p!=q)
  313.   { r = p;
  314.     p = p->forward[0];
  315.     remove_item(r);
  316.     insert_item_at_item(r,q);
  317.    }
  318.  }
  319.  
  320. void skiplist::conc(skiplist&)
  321. { error_handler(1,"sorry, not implemented: skiplist::conc(skiplist)\n"); }
  322.  
  323. void skiplist::split_at_item(skiplist_item,skiplist&,skiplist&)
  324. { error_handler(1,"sorry, not implemented: skiplist::split_at_item\n"); }
  325.  
  326.  
  327. void skiplist::print()
  328. { skiplist_item p = header;
  329.   cout << "Level = " << level << "\n"; 
  330.   for(;;)
  331.   { cout << string("<%d>  ",p);
  332.     if (p != header && p != STOP)
  333.     { cout << "key = ";
  334.       print_key(p->key);
  335.      }
  336.     newline;
  337.     for(int k=p->level;k>=0;k--)
  338.        cout << string("forward[%d] = %8d\n", k,p->forward[k]);
  339.     cout << string("backward = %8d   pred = %8d\n",p->backward, p->pred);
  340.     if (p==STOP) break;
  341.     p = p->forward[0];
  342.     newline;
  343.    }
  344. }
  345.  
  346.